import { DB } from './../db/modules';
import axios from 'axios';
import * as fs from 'fs-extra';
import * as path from 'path';
import { otherDownFile } from './otherDown';
import { taskCenter } from './task';
function mkdir(dir) {
  let dirs = dir.split('/');
  dirs.map((item, index) => {
    let dirPath = dirs.slice(0, index + 1).join('/');
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath);
    }
  });
}
function replaceStr(str, rstr) {
  let temp = str.split('/');
  temp[2] = rstr;
  return temp.join('/');
}

export async function dbDownFile(config: {
  url: string;
  localPath: string;
  parentId: string;
  index: number;
  category?: string;
  type?: string;
}) {
  let url = config.url.trim();
  let localPath = config.localPath.trim();

  let res;

  let resList = await DB.Resource.find({
    url: localPath
  });
  if (!resList.length) {
    res = await DB.Resource.create({
      target_url: url,
      url: localPath, // 资源的本地地址
      is_down: false, // 是否下载到本地
      fail_number: 0, // 资源下载的失败次数
      down_time: 0, //下载次数
      parent_id: config.parentId,
      loading: false,
      index: config.index,
      category: config.category,
      type: config.type
    });
    resList = [res];
  }
  if (resList.length > 1) {
    for (let i = 0; i < resList.length; i++) {
      let res = resList[i];

      if (!res.is_down) {
        let url = replaceStr(res.url, res.parent_id);
        await DB.Resource.updateOne(
          {
            _id: res._id
          },
          {
            url
          }
        );
        res.url = url;
      }
    }
  }
  resList.map(async function(res) {
    if (res.is_down || res.loading) {
      // 已经下载 或者下载成功
      return;
    } else {
      // if (fs.existsSync(localPath)) {
      //   // 已经有本地文件
      //   await DB.Resource.updateOne(
      //     {
      //       url: localPath
      //     },
      //     { is_down: true, loading: false }
      //   );
      // } else {
      // return;
      await DB.Resource.updateOne(
        {
          _id: res._id
        },
        {
          loading: true,
          down_time: res.down_time + 1
        }
      );
      let temp: any = () =>
        otherDownFile(res.target_url, res.url)
          .then(async a => {
            await DB.Resource.updateOne(
              {
                _id: res._id
              },
              { is_down: true, loading: false }
            );

            return a;
          })
          .catch(async data => {
            if (data.data && data.data.delete) {
              console.log('删除:', res.url, data);
              await DB.Resource.deleteOne({
                _id: res._id
              });
            } else {
              await DB.Resource.updateOne(
                {
                  _id: res._id
                },
                {
                  is_down: false,
                  loading: false,
                  fail_number: res.fail_number + 1
                }
              );
            }

            throw 0; // 下载失败
          });
      temp.other = {
        url: url
      };
      taskCenter.add(temp);
    }
  });
}

export async function downFile(url, localPath) {
  url = url.trim();
  localPath = localPath.trim();
  let timer;
  return new Promise((reslove, reject) => {
    timer = setTimeout(() => {
      console.log(' 下载20秒还没反应:', url, localPath);
      reject();
    }, 20000);
    let { dir, root, base, name, ext } = path.parse(localPath);
    mkdir(dir);
    axios({
      url,
      responseType: 'stream',
      retry: 2,
      retryDelay: 0,
      timeout: 1000 * 60 * 3,
      headers: {
        'Accept-Encoding': 'identity;q=1, *;q=0',
        Referer: url,
        'User-Agent':
          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36' +
          Math.random()

        //   'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
      }
    } as any).then(res => {
      let writer = fs.createWriteStream(localPath);
      writer.on('finish', reslove);
      writer.on('error', reject);
      res.data.pipe(writer);
      res.data.on('end', reslove);
      res.data.on('error', reject);
    }, reject);
  }).then(res => {
    clearInterval(timer);
    return res;
  });
}
